package uk.co.q3c.deplan.client.ui.mock.service;

import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import uk.co.q3c.deplan.client.domain.DomainKind;
import uk.co.q3c.deplan.client.domain.DomainObject;
import uk.co.q3c.deplan.client.domain.dag.DAG;
import uk.co.q3c.deplan.client.domain.dag.Hierarchy;
import uk.co.q3c.deplan.client.domain.task.BaseTask;
import uk.co.q3c.deplan.client.domain.task.Task;
import uk.co.q3c.deplan.client.service.TaskServiceAsync;

import com.google.gwt.user.client.rpc.AsyncCallback;
import com.googlecode.objectify.Key;

/**
 * Removes the need for a true RPC link, for test purposes. <br>
 * <br>
 * <b>LIMITATIONS:<b> <br>
 * <br>
 * keyId is not allocated in the same way as the real version - there's only one counter instead of having one for each type
 * 
 * @author David Sowerby 15 Aug 2010
 * 
 */
public class TaskRPCMock implements TaskServiceAsync {

	private long responseDelay = 100;
	private long idCount = 0;
	public boolean succeed = true;

	class Response<T> extends TimerTask {

		boolean success;
		AsyncCallback<T> callback;
		T result;

		@Override
		public void run() {
			if (success) {
				callback.onSuccess(result);
			} else {
				callback.onFailure(null);
			}

		}

	}

	Timer timer = new Timer();

	public TaskRPCMock(long responseDelay) {
		super();
		this.responseDelay = responseDelay;
	}

	@Override
	public void closeSession(AsyncCallback<Void> callback) {

	}

	@Override
	public void countPlanManagers(AsyncCallback<Integer> callback) {
		doCallback(callback, new Integer(7));
	}

	@Override
	public void countAbstractTasks(AsyncCallback<Integer> callback) {
		throw new RuntimeException("Not yet implemented");

	}

	@Override
	public void countProjects(AsyncCallback<Integer> callback) {
		throw new RuntimeException("Not yet implemented");

	}

	@Override
	public void discard(DomainObject dob, AsyncCallback<Void> callback) {
		throw new RuntimeException("Not yet implemented");

	}

	@Override
	public void findById(long id, AsyncCallback<Task> callback) {
		throw new RuntimeException("Not yet implemented");

	}

	@Override
	public void findById(DomainKind domainKind, long id, AsyncCallback<Task> callback) {
		throw new RuntimeException("Not yet implemented");

	}

	@Override
	public void findFirstByName(List<Class<? extends DomainObject>> taskClasses, String name, AsyncCallback<Task> callback) {
		throw new RuntimeException("Not yet implemented");

	}

	@Override
	public void getDag(AsyncCallback<DAG<Key<? extends Task>>> callback) {
		throw new RuntimeException("Not yet implemented");

	}

	@Override
	public void getHierarchy(AsyncCallback<Hierarchy<Key<? extends Task>>> callback) {
		throw new RuntimeException("Not yet implemented");

	}

	@Override
	public <T extends DomainObject> void getObjectFromKey(Key<T> key, AsyncCallback<T> callback) {
		throw new RuntimeException("Not yet implemented");

	}

	@Override
	public <T extends Task> void keyFor(T domainObject, AsyncCallback<Key<T>> callback) {
		throw new RuntimeException("Not yet implemented");

	}

	@Override
	public void parentOf(Task task, AsyncCallback<BaseTask> callback) {
		throw new RuntimeException("Not yet implemented");

	}

	@Override
	public void predecessorsOf(Task task, AsyncCallback<List<Task>> callback) {
		throw new RuntimeException("Not yet implemented");

	}

	@Override
	public void save(DomainObject dob, AsyncCallback<Void> callback) {
		dob.setKeyId(idCount());
		doCallback(callback, null);
	}

	@Override
	public void save(Task task, AsyncCallback<Void> callback) {
		task.setKeyId(idCount());
		doCallback(callback, null);
	}

	private Long idCount() {
		idCount++;
		return idCount;
	}

	private <T extends Object> void doCallback(AsyncCallback<T> callback, T result) {
		Response<T> response = new Response<T>();
		response.success = succeed;
		response.result = result;
		response.callback = callback;
		timer.schedule(response, responseDelay);

	}

	@Override
	public void setHierarchy(Hierarchy<Key<? extends Task>> hierarchy, AsyncCallback<Void> callback) {
		throw new RuntimeException("Not yet implemented");

	}

	@Override
	public void subTaskCountFor(BaseTask summaryTask, AsyncCallback<Integer> callback) {
		throw new RuntimeException("Not yet implemented");

	}

	@Override
	public void subTasksKeysFor(BaseTask summaryTask, AsyncCallback<List<Key<? extends Task>>> callback) {
		throw new RuntimeException("Not yet implemented");

	}

	@Override
	public void subTasksOf(BaseTask summaryTask, AsyncCallback<List<? extends Task>> callback) {
		throw new RuntimeException("Not yet implemented");

	}

	@Override
	public void successorsOf(Task abstractTask, AsyncCallback<List<Task>> callback) {
		throw new RuntimeException("Not yet implemented");

	}

	public long getResponseDelay() {
		return responseDelay;
	}

	public void setResponseDelay(long responseDelay) {
		this.responseDelay = responseDelay;
	}

	@Override
	public void childCount(BaseTask task, AsyncCallback<Integer> callback) {
		// TODO Auto-generated method stub

	}

	@Override
	public void pushDown(Task task, AsyncCallback<Void> callback) {
		// TODO Auto-generated method stub

	}

	@Override
	public void rollup(Task task, AsyncCallback<Void> callback) {
		// TODO Auto-generated method stub

	}

	@Override
	public void taskIsAtomic(Task task, AsyncCallback<Boolean> callback) {
		// TODO Auto-generated method stub

	}

}
